<?php
###############   COPYLEFT GPLv3 LICENSE   ###############
##
## JFX Version 0.2.9
## Website Management Software
## www.jfxcms.com
##
## Copyright 2009 GPLv3 - http://www.opensource.org/licenses/gpl-3.0.html
##
## Anthony Gallon
## oi_antz@hotmail.com
##
## Permission is hereby granted to any person having a copy of this software
## to freely use and modify as required so long as the copyright notices
## and branding remain intact.
##
## Full license details available at http://www.jfxcms.com/license
##
###############   COPYLEFT GPLv3 LICENSE   ###############

class JFX_Module_Croncontrol extends JFX_Module
{
    public $keyname = 'croncontrol';
    public $title = 'Cron Control';
    public $version = '0.0.1';

    public function __construct(){
        parent::__construct();
		$this->title = $this->lang('module_title');
    }

    public function admin(){
        //  get objects
        $SMARTY = JFX::registry('Smarty');
        $DB = JFX::registry('db');
        $CONFIG = JFX::registry('config');

        $this->addStyleSheet('admin.css');

        $SMARTY->assign('ccUrl', $this->adminUrl);

        // figure out the requested file
        $request = explode('?', $_SERVER['REQUEST_URI']);
        $request = str_replace('..', '', $request[0]);
        $request = trim($request, '/');
        $request = explode('/', $request);

        foreach($request as $k=>$foldername){
            if($foldername == '..'){
                unset($request[$k]);
                continue;
            }
            if($foldername === $this->keyname){
                unset($request[$k]);
                break;
            }else{
                unset($request[$k]);
            }
        }
        $request = array_regenerate_keys($request);
        if(count($request) > 0 && file_exists($this->dirname.'/actions/'.$request[0].'.php')){
            $requestedFile = $request[0];
        }else{
            // use default
            $requestedFile = 'default';
        }

        if($requestedFile == 'edit') $SMARTY->assign('activeTab', 'default');
        else $SMARTY->assign('activeTab', $requestedFile);

        // now we have a valid request, render the tabs
        $SMARTY->assign('activeTab', $requestedFile);
        echo $this->fetchTemplate('tabs.tpl');

        // dispatch the action
        echo '<div id="admin-content">';
        include($this->dirname.'/actions/'.$requestedFile.'.php');
        echo '</div>';
    }

    public function findNextRun($schedule){

        if(trim($schedule)=='@reboot'){
            JFX::addError($this->lang('reboot_not_supported'));
            return false;
        }

        switch(trim($schedule)){
            case '@yearly':
            case '@annually':
                $schedule = '0 0 1 1 *';
            break;
            case '@monthly':
                $schedule = '0 0 1 * *';
            break;
            case '@weekly':
                $schedule = '0 0 * * 0';
            break;
            case '@daily':
                $schedule = '0 0 * * *';
            break;
            case '@midnight':
                $schedule = '0 0 * * *';
            break;
            case '@hourly':
                $schedule = '0 * * * *';
            break;
        }

        $parts = array(0=>'');
        $strlen = strlen($schedule);
        $count = 0;
        $open = true;
        for($i=0; $i<$strlen; $i++){
            if(trim($schedule{$i})==''){
                if($open){
                    continue;
                }else{
                    $open = true;
                    $count++;
                    $parts[$count] = '';
                    continue;
                }
            }else{
                $parts[$count] .= $schedule{$i};
                $open = false;
            }
        }

        if($parts[0] !== '*'){
            if(intval($parts[0])<0 || intval($parts[0])>59){
                JFX::addError($this->lang('minute_out_of_range'));
                return false;
            }
        }

        if($parts[1] !== '*'){
            if(intval($parts[1])<0 || intval($parts[1])>23){
                JFX::addError($this->lang('hour_out_of_range'));
                return false;
            }
        }

        if($parts[2] !== '*'){
            if(intval($parts[2])<1 || intval($parts[2])>31){
                JFX::addError($this->lang('hour_out_of_range'));
                return false;
            }
        }

        if($parts[3] !== '*'){
            if(intval($parts[3])<1 || intval($parts[3])>12){
                JFX::addError($this->lang('dom_out_of_range'));
                return false;
            }
        }

        if($parts[4] !== '*'){
            if(intval($parts[4])<0 || intval($parts[4])>6){
                JFX::addError($this->lang('dow_out_of_range'));
                return false;
            }
        }

        // valid schedule!
        $curParts = array(
            0 => (int) date('i'),
            1 => (int) date('G'),
            2 => (int) date('j'),
            3 => (int) date('n'),
            4 => (int) date('w')
        );

        $newParts = array();

        $hour = 0;
        $min = 0;
        $sec = date('s');
        $dayOfWeek = 0;
        $dayOfMonth = 0;
        $month = 0;
        $year = (int) date('Y');

        $numParts = count($parts);
        for($i=$numParts; $i>=0; $i--){
            $sched = $parts[$i];
            $curTime = $curParts[$i];
            if($sched === '*'){
                // next interval will do
                $newTime = $parts[$i];
                switch($i){
                    case 0:
                        $min = $curTime+1;
                    break;
                    case 1:
                        $hour = $curTime;
                    break;
                    case 2:
                        $dayOfMonth = $curTime;
                    break;
                    case 3:
                        $month = $curTime;
                    break;
                    case 4:
                        $dayOfWeek = ($curParts[2]+1) + $newTime;
                    break;
                }
            }else{
                $newTime = $parts[$i];
                switch($i){
                    case 0:
                        $min = $newTime;
                    break;
                    case 1:
                        $hour = $newTime;
                    break;
                    case 2:
                        $dayOfMonth = $newTime;
                    break;
                    case 3:
                        $month = $newTime;
                    break;
                    case 4:
                        $dayOfWeek = ($curParts[2]+1) + $newTime;
                    break;
                }
            }

            if($dayOfWeek > $curParts[2] && $dayOfMonth > $curParts[2]){
                if($dayOfWeek > $dayOfMonth){
                    $day = $dayOfMonth;
                }else{
                    $day = $dayOfWeek;
                }
            }else if($dayOfWeek > $curParts[2]){
                $day = $dayOfWeek;
            }else{
                $day = $dayOfMonth;
            }

            if($day < $curParts[2]){
                $month++;
            }

            $newParts[$i] = (int) $newTime;
            if($min > 59){
                $min = 0;
                $hour++;
            }
            if($hour > 23){
                $hour = 0;
                $day++;
            }
            $daysInMonth = (int) date('t');
            if($day > $daysInMonth){
                $day = 0;
                $month++;
            }
            if($month > 12){
                $month = 1;
                $year++;
            }
            
        }

        $tstamp = mktime($hour, $min, $sec, $month, $day, $year);
        
        return $tstamp;
    }


    public function install(){
        include($this->dirname.'/install/install.php');
    }

    public function uninstall(){
        include($this->dirname.'/install/uninstall.php');
    }

}